Imports System.Runtime.CompilerServices
Imports System.Drawing.Drawing2D

Public Module Extensions

    <Extension()> _
    Function Between(ByVal n As Integer, ByVal n1 As Integer, ByVal n2 As Integer)
        Return n >= n1 And n <= n2
    End Function

    <Extension()> _
    Function StandsBetween(ByVal n As Integer, ByVal n1 As Integer, ByVal n2 As Integer)
        Return (n > n1 And n < n2) Or (n > n2 And n < n1)
    End Function

    <Extension()> _
    Sub Append(ByRef s As String, ByVal t As String)
        s &= t & vbCrLf
    End Sub

    <Extension()> _
    Function [In](ByVal c As Char, ByVal ParamArray t() As Char) As Boolean
        For Each Item In t
            If c = Item Then Return True
        Next
        Return False
    End Function

    <Extension()> _
    Function [In](ByVal c As Integer, ByVal ParamArray t() As Integer) As Boolean
        For Each Item In t
            If c = Item Then Return True
        Next
        Return False
    End Function

    <Extension()> _
    Function [In](ByVal Cell As PuzzleStudio.Cell, ByVal ParamArray Cells() As PuzzleStudio.Cell) As Boolean
        For Each Item In Cells
            If Cell.i = Item.i Then Return True
        Next
        Return False
    End Function

    <Extension()> _
    Function IsEqual(ByVal s1 As List(Of Char), ByVal s2 As String) As Boolean
        Return CStr(s1.ToArray) = s2
    End Function

    <Extension()> _
    Function IsEqual(ByVal s1 As List(Of Char), ByVal s2 As List(Of Char)) As Boolean
        Return CStr(s1.ToArray) = CStr(s2.ToArray)
    End Function

    <Extension()> _
    Function Add(ByVal s1 As String, ByVal s2 As String) As String
        Dim Arr = s1.ToArray.Union(s2.ToArray).ToArray
        Array.Sort(Arr)
        Return CStr(Arr)
    End Function

    Function Centered() As StringFormat
        Dim Format As New StringFormat
        Format.Alignment = StringAlignment.Center
        Format.LineAlignment = StringAlignment.Center
        Return Format
    End Function

    Function LeftAligned() As StringFormat
        Dim Format As New StringFormat
        Format.Alignment = StringAlignment.Near
        Format.LineAlignment = StringAlignment.Near
        Return Format
    End Function

    Function Range(ByVal First As Integer, ByVal Last As Integer) As List(Of Integer)
        Return Enumerable.Range(First, Last - First + 1).ToList
    End Function

    Function Range(ByVal First As Integer, ByVal Last As Integer, ByVal [Step] As Integer) As List(Of Integer)
        Return (From i In Enumerable.Range(0, (Last - First + 1) / 2) Select First + [Step] * i).ToList
    End Function

    <Extension()> _
    Function ExcludeLast(ByVal s As String, ByVal Exclude As Integer) As String
        Return Left(s, Len(s) - Exclude)
    End Function

    <Extension()> _
    Sub DrawImageWithOpacity(ByVal G As Graphics, ByVal B As Image, ByVal DestRect As Rectangle, Optional ByVal Opacity As Double = 1)
        G.InterpolationMode = InterpolationMode.HighQualityBicubic
        G.PixelOffsetMode = PixelOffsetMode.HighQuality
        Dim Attr As New Imaging.ImageAttributes
        Dim Matrix As New Imaging.ColorMatrix(New Single()() {New Single() {1, 0, 0, 0, 0}, New Single() {0, 1, 0, 0, 0}, New Single() {0, 0, 1, 0, 0}, New Single() {0, 0, 0, Opacity, 0}, New Single() {0, 0, 0, 0, 1}})
        Attr.SetColorMatrix(Matrix)
        If B Is Nothing Then Exit Sub
        G.DrawImage(B, DestRect, 0, 0, B.Width, B.Height, GraphicsUnit.Pixel, Attr)
    End Sub

End Module
